package com.ffcs.cn.action.myButton;


import com.supermap.data.Dataset;
import com.supermap.data.DatasetType;
import com.supermap.data.Datasource;
import com.supermap.desktop.controls.ui.controls.DialogResult;
import com.supermap.desktop.controls.ui.controls.SmDialog;
import com.supermap.desktop.controls.ui.controls.button.SmButton;
import com.supermap.desktop.controls.ui.controls.comboBox.SmComboBoxDataset;
import com.supermap.desktop.controls.ui.controls.comboBox.SmComboBoxDatasource;
import com.supermap.desktop.controls.utilities.ComponentFactory;
import com.supermap.desktop.controls.utilities.MapViewUIUtilities;
import com.supermap.desktop.core.Interface.IFormMap;
import com.supermap.desktop.core.enums.WindowType;
import com.supermap.desktop.core.ui.controls.GridBagConstraintsHelper;
import com.supermap.desktop.core.utilties.DefaultValues;
import com.supermap.desktop.core.utilties.FormUtilities;

import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionListener;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;


/**
 * @version 1.0-SNAPSHOT
 */
public class MyDialog extends SmDialog {
    public static void main(String[] args) {
        new MyDialog().showDialog();
    }
    // 声明对话框中的各个组件
    private JPanel panelSourceData = new JPanel(); // 主数据源选择面板
    private JLabel datasourceLabel = new JLabel(); // "数据源:" 标签
    private SmComboBoxDatasource datasourceSelect = new SmComboBoxDatasource(); // 数据源选择下拉框
    private JLabel datasetLabel = new JLabel(); // "数据集" 标签
    private SmComboBoxDataset datasetSelect = new SmComboBoxDataset(); // 数据集选择下拉框

    // 操作按钮（确认和取消）
    private SmButton buttonOK = ComponentFactory.createButtonOK(); // 使用工厂方法创建确认按钮
    private SmButton buttonCancel = ComponentFactory.createButtonCancel(); // 使用工厂方法创建取消按钮

    public MyDialog() {
        super();

        //=================================属性=================================
        //数据源
        Datasource selectedDatasource = this.datasourceSelect.getSelectedDatasource();
        //数据集
        Dataset selectedDataset = this.datasetSelect.getSelectedDataset();


        //=================================数据源和数据集初始化=================================
        // 初始化数据源相关设置
        this.datasourceSelect.setIncludeReadOnly(false); // 过滤只读数据源
        this.datasetSelect.setSupportedDatasetTypes(DatasetType.POINT); // 只允许选择点类型数据集
        // 如果当前已选择数据源，则初始化数据集下拉框
        if (this.datasourceSelect.getSelectedDatasource() != null) {
            this.datasetSelect.setDatasource(this.datasourceSelect.getSelectedDatasource());
        }
        // 当数据集下拉框有选中项时启用按钮
        this.buttonOK.setEnabled(this.datasetSelect.getSelectedDataset() != null);


        // =================================数据源和数据集尺寸=================================
        // 设置标签的默认尺寸
        this.datasourceLabel.setPreferredSize(DefaultValues.getLabelDefaultSize());
        this.datasourceLabel.setText("数据源:"); // 数据源标签文本
        this.datasetLabel.setPreferredSize(DefaultValues.getLabelDefaultSize());
        this.datasetLabel.setText("数据集"); // 数据集标签文本


        // =================================数据源与下拉框、数据集与下拉框添加到子面板=================================
        // 初始化数据源面板布局（使用网格包布局）
        this.panelSourceData.setLayout(new GridBagLayout());
        // 添加数据源标签到面板（使用网格约束助手）
        this.panelSourceData.add(this.datasourceLabel,
                new GridBagConstraintsHelper(0, 0, 1, 1) // 第0行第0列，占1x1单元格
                        .setInsets(GridBagConstraintsHelper.CONTROLS_GAP, GridBagConstraintsHelper.CONTROLS_GAP, 0, 0));
        //添加数据源下拉框到面板（使用网格约束助手）
        this.panelSourceData.add(this.datasourceSelect,
                new GridBagConstraintsHelper(1, 0, 1, 1) // 第0行第1列
                        .setWeight(1, 0).setAnchor(GridBagConstraints.CENTER) // 水平拉伸
                        .setFill(GridBagConstraints.HORIZONTAL)
                        .setInsets(GridBagConstraintsHelper.CONTROLS_GAP, GridBagConstraintsHelper.CONTROLS_GAP, 0, GridBagConstraintsHelper.CONTROLS_GAP));
        // 添加数据集标签到面板
        this.panelSourceData.add(this.datasetLabel,
                new GridBagConstraintsHelper(0, 1, 1, 1) // 第1行第0列
                        .setInsets(GridBagConstraintsHelper.CONTROLS_GAP, GridBagConstraintsHelper.CONTROLS_GAP, 0, 0));
        // 添加数据集下拉框到面板
        this.panelSourceData.add(this.datasetSelect,
                new GridBagConstraintsHelper(1, 1, 1, 1) // 第1行第1列
                        .setWeight(1, 0).setFill(GridBagConstraints.HORIZONTAL) // 水平拉伸
                        .setInsets(GridBagConstraintsHelper.CONTROLS_GAP, GridBagConstraintsHelper.CONTROLS_GAP, 0, GridBagConstraintsHelper.CONTROLS_GAP));


        // =================================设置主面板添加按钮和子面板=================================
        // 设置对话框主布局
        this.setSize(new Dimension(430, 160));
        // 设置界面文本
        this.setTitle("添加到新地图"); // 对话框标题
        // 设置对话框主布局（网格包布局）
        this.setLayout(new GridBagLayout());
        // 添加对话框（数据源面板）到主布局（顶部）
        this.add(this.panelSourceData,
                new GridBagConstraintsHelper(0, 0, 1, 1)
                        .setInsets(GridBagConstraintsHelper.FRAME_CONTROL_GAP, GridBagConstraintsHelper.FRAME_CONTROL_GAP, 0, GridBagConstraintsHelper.FRAME_CONTROL_GAP)
                        .setWeight(1, 0).setFill(GridBagConstraints.HORIZONTAL));
        // 添加空白面板占位（中间区域，用于扩展空间）
        this.add(new JPanel(),
                new GridBagConstraintsHelper(0, 2, 1, 1)
                        .setInsets(0, GridBagConstraintsHelper.FRAME_CONTROL_GAP, 0, GridBagConstraintsHelper.FRAME_CONTROL_GAP)
                        .setFill(GridBagConstraints.BOTH).setWeight(1, 1));

        // 添加按钮面板到底部
        this.add(
                // ComponentFactory 是一个工厂类，用于创建各种组件
                // createButtonPanel 是 ComponentFactory 类中的一个静态方法，用于创建一个按钮面板
                // this.buttonOK 和 this.buttonCancel 分别是当前类中定义的两个按钮对象
                // 该方法会将这两个按钮添加到一个面板中，并返回这个面板组件
                ComponentFactory.createButtonPanel(this.buttonOK, this.buttonCancel),
                // GridBagConstraintsHelper 是一个自定义的辅助类，用于简化 GridBagConstraints 对象的创建和设置
                // 这里创建了一个 GridBagConstraintsHelper 对象，并传入了四个参数，用于设置组件在 GridBagLayout 中的位置和大小
                new GridBagConstraintsHelper(0, 3, 1, 1)
                        // setInsets 方法用于设置组件的内边距，即组件与容器边缘以及其他组件之间的间距
                        // 这里传入了四个参数，分别表示上、左、下、右的间距
                        // 0 表示上方没有间距
                        // GridBagConstraintsHelper.FRAME_CONTROL_GAP 是一个常量，用于表示左、下、右的间距
                        .setInsets(0, GridBagConstraintsHelper.FRAME_CONTROL_GAP, GridBagConstraintsHelper.FRAME_CONTROL_GAP, GridBagConstraintsHelper.FRAME_CONTROL_GAP)
                        // setWeight 方法用于设置组件在水平和垂直方向上的权重
                        // 权重决定了在容器大小改变时，组件如何分配额外的空间
                        // 这里设置水平方向的权重为 1，垂直方向的权重为 0，表示在水平方向上组件会尽量填充可用空间，而在垂直方向上不会扩展
                        .setWeight(1, 0)
                        // setFill 方法用于设置组件在其显示区域内的填充方式
                        // GridBagConstraints.HORIZONTAL 表示组件将在水平方向上填充其显示区域
                        .setFill(GridBagConstraints.HORIZONTAL));


        // =================================注册事件监听器=================================
        // 数据源下拉框选择变化监听
        this.datasourceSelect.addItemListener(this.itemListenerDatasource);
        // 确认按钮点击监听
        this.buttonOK.addActionListener(this.actionListenerOK);
        // 取消按钮点击监听
        this.buttonCancel.addActionListener(this.actionListenerCancel);


        // 将按钮添加到组件列表（可能用于焦点遍历）
        this.componentList.add(this.buttonOK);
        this.componentList.add(this.buttonCancel);
        // 设置焦点遍历策略
        this.setFocusTraversalPolicy(this.policy);
    }


    /**
     * 数据源选择变化监听器实现
     */
    private final ItemListener itemListenerDatasource = new ItemListener() {
        @Override
        public void itemStateChanged(ItemEvent e) {
            // 当选中新选项时
            if (e.getStateChange() == ItemEvent.SELECTED) {
                // 更新数据集下拉框的数据源
                datasetSelect.setDatasource(datasourceSelect.getSelectedDatasource());
                // 修改确定按钮的点击状态
                checkoutButtonOK();
            }
        }
    };

    /**
     * 确认按钮点击事件处理（Lambda表达式）
     */
    private final ActionListener actionListenerOK = e -> {
        //========================核心业务逻辑方法========================
        // 创建新的地图窗口
        IFormMap formMap = (IFormMap) FormUtilities.fireNewWindowEvent(WindowType.MAP);
        // 将选中的数据集添加到地图的0号图层
        MapViewUIUtilities.addDatasetsToMap(
                formMap.getMapControl().getMap(),
                0,
                datasetSelect.getSelectedDataset()
        );

        // 设置对话框结果为OK
        setDialogResult(DialogResult.OK);
        // 关闭对话框
        dispose();
    };

    /**
     * 取消按钮点击事件处理（直接关闭对话框）
     */
    private final ActionListener actionListenerCancel = e -> {
        dispose();
    };

    /**
     * 修改确定按钮的点击状态
     */
    private void checkoutButtonOK() {
        // 当数据集下拉框有选中项时启用按钮
        this.buttonOK.setEnabled(this.datasetSelect.getSelectedDataset() != null);
    }

}
